<!DOCTYPE html>
<html>
<head>
    <!-- hexo-inject:begin --><!-- hexo-inject:end --><title>博望</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.css">
    <link href="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css">
    <script src="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    
<link rel="stylesheet" href="/css/prism.css">
 
    
<script src="/js/prism.js"></script>

    
    
<link rel="stylesheet" href="/css/index.css">
 
    
<script src="/js/search.js"></script>



     
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML" async></script>
        <script type="text/x-mathjax-config">
            MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
        </script>
     

     
        <script src="//lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js"> </script>
        
<script src="/js/fancybox.js"></script>

    

    <script type="text/javascript">
        var search_path = "search.xml";
        if (search_path.length == 0) {
            search_path = "search.xml";
        }
        var path = "/" + search_path;
        searchFunc(path, 'local-search-input', 'local-search-result');
    </script>
<!-- hexo injector head_end start -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/themes/prism.css">
<!-- hexo injector head_end end --><meta name="generator" content="Hexo 6.1.0"><!-- hexo-inject:begin --><!-- hexo-inject:end --></head>

    <style>
        .row2 {
            /* --bs-gutter-x: 2.5rem;
            --bs-gutter-y: 0;
            display: flex;
            flex-wrap: wrap;
            margin-top: calc(var(--bs-gutter-y) * -20);
            margin-right: calc(var(--bs-gutter-x) * -2);
            margin-left: calc(var(--bs-gutter-x) * -2); */
        }

        .row-0 {
            width: 0;
        }
    </style>

    <body id="body">
        <!-- hexo-inject:begin --><!-- hexo-inject:end --><!-- 导航栏 -->
        <nav class="navbar navbar-expand-md navbar-dark mb-4 pt-3 pb-3">
    <div class="container" style="display: flex;flex-direction: row;align-items: flex-end;">
        <div style="display: flex;flex-direction: column;">
            <a class="navbar-brand" style='font: bold 29px "Times New Roman", Georgia, Times, sans-serif;
        color: #555;' href="/ ">
                博望
            </a>
            <span style="padding-bottom:7px;padding-right:20px">
                博望不熄
            </span>
        </div>

        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse"
            aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse" id="navbarCollapse">
            <ul class="navbar-nav me-auto mb-2 mb-md-0" style="color: #555;">
                
 
 

    <li class="nav-item">
        <a class="nav-link" style="color: #555;" href="/">
            <i class="fa fa-home "> </i> 主页
        </a>
    </li>

    <li class="nav-item">
        <a class="nav-link" style="color: #555;" href="/archives">
            <i class="fa fa-archive" "> </i> 归档
        </a>
    </li>
 

            </ul>

            
                <form class="d-flex">
                    <button class="btn text-muted fa fa-search d-none d-md-block d-lg-block" disabled></button>
                    <input id="local-search-input" class="form-control me-2 pe-4" type="search"
                        placeholder="搜索 " aria-label="Search">
                </form>
                

                    <ul class="navbar-nav">
                        
 

                    </ul>
        </div>
    </div>
</nav>

            <main class="container">
                <div class="row row2 pt-3">
                    <!-- 文章 -->
                    <div id="content" class="col-md-12">
                        <div class="markdown-section">
                            <!-- 搜索结果 -->
                            <div id="local-search-result"></div>
                            <!-- 博客详情 -->
<p class="h1">QuickJS字节码打印</p>

<div class="pb-3">
    <i class="fa fa-calendar p-1"></i>
    2022/05/05 10:36:08 

    <i class="fa fa-folder-open p-1"> </i> 
    <span class="tag-hover">
        
            <a href="/categories/QuickJS/ " class="link-dark text-decoration-none"> 
                QuickJS 
            </a>
         
    </span>

    <i class="fa fa-tag p-1"> </i>
    <span class="tag-hover">
        
            <a href="/tags/QuickJS/" class="link-dark text-decoration-none"> 
                QuickJS 
            </a>
        
    </span>
</div>

<h2 id="字节码打印"><a href="#字节码打印" class="headerlink" title="字节码打印"></a>字节码打印</h2><p>QuickJS执行JavaScript代码时，先将源码解析成字节码，然后再执行字节码。字节码由操作码和操作数组成。QuickJS支持字节码的打印。我们只需要开启一个宏定义即可将字节码打印出来。</p>
<pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">/* dump the bytecode of the compiled functions: combination of bits
   1: dump pass 3 final byte code
   2: dump pass 2 code
   4: dump pass 1 code
   8: dump stdlib functions
  16: dump bytecode in hex
  32: dump line number table
 */</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">DUMP_BYTECODE</span>  <span class="token expression"><span class="token punctuation">(</span><span class="token number">7</span><span class="token punctuation">)</span></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>QuickJS将JavaScript代码转化成字节码时，有三个阶段。第一个阶段，解析JavaScript源码，生成最原始的字节码；第二阶段，处理变量相关的功能。确定变量来源和作用域，然后将其字节码换成更确切的字节码；第三个阶段确定label跳转地址，合并指令，计算栈的长度。此外，我们还可以打印stdilb函数、十六进制的字节码和行号表。可以根据需要打印的内容，定义DUMP_BYTECODE的值。</p>
<pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">//字节码打印代码之一</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">if</span> <span class="token expression"><span class="token function">defined</span><span class="token punctuation">(</span>DUMP_BYTECODE<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>DUMP_BYTECODE <span class="token operator">&amp;</span> <span class="token number">4</span><span class="token punctuation">)</span></span></span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>fd<span class="token operator">-></span>js_mode <span class="token operator">&amp;</span> JS_MODE_STRIP<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"pass 1\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">dump_byte_code</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> fd<span class="token operator">-></span>byte_code<span class="token punctuation">.</span>buf<span class="token punctuation">,</span> fd<span class="token operator">-></span>byte_code<span class="token punctuation">.</span>size<span class="token punctuation">,</span>
                       fd<span class="token operator">-></span>args<span class="token punctuation">,</span> fd<span class="token operator">-></span>arg_count<span class="token punctuation">,</span> fd<span class="token operator">-></span>vars<span class="token punctuation">,</span> fd<span class="token operator">-></span>var_count<span class="token punctuation">,</span>
                       fd<span class="token operator">-></span>closure_var<span class="token punctuation">,</span> fd<span class="token operator">-></span>closure_var_count<span class="token punctuation">,</span>
                       fd<span class="token operator">-></span>cpool<span class="token punctuation">,</span> fd<span class="token operator">-></span>cpool_count<span class="token punctuation">,</span> fd<span class="token operator">-></span>source<span class="token punctuation">,</span> fd<span class="token operator">-></span>line_num<span class="token punctuation">,</span>
                       fd<span class="token operator">-></span>label_slots<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>

<span class="token comment">//操作码</span>
<span class="token keyword">typedef</span> <span class="token keyword">struct</span> <span class="token class-name">JSOpCode</span> <span class="token punctuation">&#123;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifdef</span> <span class="token expression">DUMP_BYTECODE</span></span>
    <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>name<span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
    <span class="token class-name">uint8_t</span> size<span class="token punctuation">;</span> <span class="token comment">/* in bytes */</span>
    <span class="token comment">/* the opcodes remove n_pop items from the top of the stack, then
       pushes n_push items */</span>
    <span class="token class-name">uint8_t</span> n_pop<span class="token punctuation">;</span>
    <span class="token class-name">uint8_t</span> n_push<span class="token punctuation">;</span>
    <span class="token class-name">uint8_t</span> fmt<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span> JSOpCode<span class="token punctuation">;</span>


<span class="token comment">//tab表示字节码数组，len字节码数组长度</span>
<span class="token comment">//args表示函数参数数组，arg_count函数参数个数</span>
<span class="token comment">//vars表示函数变量，var_count函数变量个数</span>
<span class="token comment">//closure_var表示函数闭包变量，closure_var_count闭包变量数量</span>
<span class="token comment">//cpool 是一个 JSValue 结构体，JSValue 是最基本的单位，这个结构体会有一个 tag 来标示 JSValue 的类型，值是保存在 JSValueUnion 里，值可以是整型和浮点，也可以是一个对象的指针，指针指向的对象是由引用计数来进行管理的，引用计数结构体是 JSRefCountHeader。这里 JSValue 的值是个数组。</span>
<span class="token comment">//source表示源码数组 line_num行号</span>
<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">dump_byte_code</span><span class="token punctuation">(</span>JSContext <span class="token operator">*</span>ctx<span class="token punctuation">,</span> <span class="token keyword">int</span> pass<span class="token punctuation">,</span>
                           <span class="token keyword">const</span> <span class="token class-name">uint8_t</span> <span class="token operator">*</span>tab<span class="token punctuation">,</span> <span class="token keyword">int</span> len<span class="token punctuation">,</span>
                           <span class="token keyword">const</span> JSVarDef <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token keyword">int</span> arg_count<span class="token punctuation">,</span>
                           <span class="token keyword">const</span> JSVarDef <span class="token operator">*</span>vars<span class="token punctuation">,</span> <span class="token keyword">int</span> var_count<span class="token punctuation">,</span>
                           <span class="token keyword">const</span> JSClosureVar <span class="token operator">*</span>closure_var<span class="token punctuation">,</span> <span class="token keyword">int</span> closure_var_count<span class="token punctuation">,</span>
                           <span class="token keyword">const</span> JSValue <span class="token operator">*</span>cpool<span class="token punctuation">,</span> <span class="token class-name">uint32_t</span> cpool_count<span class="token punctuation">,</span>
                           <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>source<span class="token punctuation">,</span> <span class="token keyword">int</span> line_num<span class="token punctuation">,</span>
                           <span class="token keyword">const</span> LabelSlot <span class="token operator">*</span>label_slots<span class="token punctuation">,</span> JSFunctionBytecode <span class="token operator">*</span>b<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    <span class="token keyword">const</span> JSOpCode <span class="token operator">*</span>oi<span class="token punctuation">;</span>
    <span class="token keyword">int</span> pos<span class="token punctuation">,</span> pos_next<span class="token punctuation">,</span> op<span class="token punctuation">,</span> size<span class="token punctuation">,</span> idx<span class="token punctuation">,</span> addr<span class="token punctuation">,</span> line<span class="token punctuation">,</span> line1<span class="token punctuation">,</span> in_source<span class="token punctuation">;</span>
    <span class="token class-name">uint8_t</span> <span class="token operator">*</span>bits <span class="token operator">=</span> <span class="token function">js_mallocz</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> len <span class="token operator">*</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token operator">*</span>bits<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    BOOL use_short_opcodes <span class="token operator">=</span> <span class="token punctuation">(</span>b <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">/* scan for jump targets */</span>
    <span class="token comment">//遍历字节码，将字节码中是label的地方寻找出来并标记到bits数组中。</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span>pos <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> pos <span class="token operator">&lt;</span> len<span class="token punctuation">;</span> pos <span class="token operator">=</span> pos_next<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        op <span class="token operator">=</span> tab<span class="token punctuation">[</span>pos<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">//获取操作码字节</span>
        <span class="token comment">//将字节码转化成操作码</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>use_short_opcodes<span class="token punctuation">)</span>
            oi <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token function">short_opcode_info</span><span class="token punctuation">(</span>op<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">else</span>
            oi <span class="token operator">=</span> <span class="token operator">&amp;</span>opcode_info<span class="token punctuation">[</span>op<span class="token punctuation">]</span><span class="token punctuation">;</span>
        <span class="token comment">//更具操作码长度，计算下一个操作码位置</span>
        pos_next <span class="token operator">=</span> pos <span class="token operator">+</span> oi<span class="token operator">-></span>size<span class="token punctuation">;</span>
        <span class="token comment">//判断字节码是否正确，只有正确才解析</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>op <span class="token operator">&lt;</span> OP_COUNT<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token comment">//判断操作码的格式</span>
            <span class="token keyword">switch</span> <span class="token punctuation">(</span>oi<span class="token operator">-></span>fmt<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">if</span> <span class="token expression">SHORT_OPCODES</span></span>
            <span class="token keyword">case</span> OP_FMT_label8<span class="token operator">:</span>
                pos<span class="token operator">++</span><span class="token punctuation">;</span>
                addr <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">int8_t</span><span class="token punctuation">)</span>tab<span class="token punctuation">[</span>pos<span class="token punctuation">]</span><span class="token punctuation">;</span>
                <span class="token keyword">goto</span> has_addr<span class="token punctuation">;</span>
            <span class="token keyword">case</span> OP_FMT_label16<span class="token operator">:</span>
                pos<span class="token operator">++</span><span class="token punctuation">;</span>
                addr <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">int16_t</span><span class="token punctuation">)</span><span class="token function">get_u16</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">goto</span> has_addr<span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
            <span class="token keyword">case</span> OP_FMT_atom_label_u8<span class="token operator">:</span>
            <span class="token keyword">case</span> OP_FMT_atom_label_u16<span class="token operator">:</span>
                pos <span class="token operator">+=</span> <span class="token number">4</span><span class="token punctuation">;</span>
                <span class="token comment">/* fall thru */</span>
            <span class="token keyword">case</span> OP_FMT_label<span class="token operator">:</span>
            <span class="token keyword">case</span> OP_FMT_label_u16<span class="token operator">:</span>
                pos<span class="token operator">++</span><span class="token punctuation">;</span>
                addr <span class="token operator">=</span> <span class="token function">get_u32</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">goto</span> has_addr<span class="token punctuation">;</span>
            has_addr<span class="token operator">:</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>pass <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span>
                    addr <span class="token operator">=</span> label_slots<span class="token punctuation">[</span>addr<span class="token punctuation">]</span><span class="token punctuation">.</span>pos<span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>pass <span class="token operator">==</span> <span class="token number">2</span><span class="token punctuation">)</span>
                    addr <span class="token operator">=</span> label_slots<span class="token punctuation">[</span>addr<span class="token punctuation">]</span><span class="token punctuation">.</span>pos2<span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>pass <span class="token operator">==</span> <span class="token number">3</span><span class="token punctuation">)</span>
                    addr <span class="token operator">+=</span> pos<span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>addr <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> addr <span class="token operator">&lt;</span> len<span class="token punctuation">)</span>
                    bits<span class="token punctuation">[</span>addr<span class="token punctuation">]</span> <span class="token operator">|=</span> <span class="token number">1</span><span class="token punctuation">;</span>
                <span class="token keyword">break</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span>
        <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span>
    in_source <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>source<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token comment">/* Always print first line: needed if single line */</span>
        <span class="token function">print_lines</span><span class="token punctuation">(</span>source<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        in_source <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
    line1 <span class="token operator">=</span> line <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
    pos <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token comment">//遍历</span>
    <span class="token keyword">while</span> <span class="token punctuation">(</span>pos <span class="token operator">&lt;</span> len<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        op <span class="token operator">=</span> tab<span class="token punctuation">[</span>pos<span class="token punctuation">]</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>source<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>b<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                line1 <span class="token operator">=</span> <span class="token function">find_line_num</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> b<span class="token punctuation">,</span> pos<span class="token punctuation">)</span> <span class="token operator">-</span> line_num <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>op <span class="token operator">==</span> OP_line_num<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                line1 <span class="token operator">=</span> <span class="token function">get_u32</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">-</span> line_num <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>line1 <span class="token operator">></span> line<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>in_source<span class="token punctuation">)</span>
                    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                in_source <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
                <span class="token function">print_lines</span><span class="token punctuation">(</span>source<span class="token punctuation">,</span> line<span class="token punctuation">,</span> line1<span class="token punctuation">)</span><span class="token punctuation">;</span>
                line <span class="token operator">=</span> line1<span class="token punctuation">;</span>
                <span class="token comment">//bits[pos] |= 2;</span>
            <span class="token punctuation">&#125;</span>
        <span class="token punctuation">&#125;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>in_source<span class="token punctuation">)</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        in_source <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>op <span class="token operator">>=</span> OP_COUNT<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"invalid opcode (0x%02x)\n"</span><span class="token punctuation">,</span> op<span class="token punctuation">)</span><span class="token punctuation">;</span>
            pos<span class="token operator">++</span><span class="token punctuation">;</span>
            <span class="token keyword">continue</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>use_short_opcodes<span class="token punctuation">)</span>
            oi <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token function">short_opcode_info</span><span class="token punctuation">(</span>op<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">else</span>
            oi <span class="token operator">=</span> <span class="token operator">&amp;</span>opcode_info<span class="token punctuation">[</span>op<span class="token punctuation">]</span><span class="token punctuation">;</span>
        size <span class="token operator">=</span> oi<span class="token operator">-></span>size<span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>pos <span class="token operator">+</span> size <span class="token operator">></span> len<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"truncated opcode (0x%02x)\n"</span><span class="token punctuation">,</span> op<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">if</span> <span class="token expression"><span class="token function">defined</span><span class="token punctuation">(</span>DUMP_BYTECODE<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>DUMP_BYTECODE <span class="token operator">&amp;</span> <span class="token number">16</span><span class="token punctuation">)</span></span></span>
        <span class="token punctuation">&#123;</span>
            <span class="token keyword">int</span> i<span class="token punctuation">,</span> x<span class="token punctuation">,</span> x0<span class="token punctuation">;</span>
            x <span class="token operator">=</span> x0 <span class="token operator">=</span> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"%5d "</span><span class="token punctuation">,</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> size<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">==</span> <span class="token number">6</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n%*s"</span><span class="token punctuation">,</span> x <span class="token operator">=</span> x0<span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">&#125;</span>
                x <span class="token operator">+=</span> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %02X"</span><span class="token punctuation">,</span> tab<span class="token punctuation">[</span>pos <span class="token operator">+</span> i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"%*s"</span><span class="token punctuation">,</span> x0 <span class="token operator">+</span> <span class="token number">20</span> <span class="token operator">-</span> x<span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
        <span class="token comment">//打印label</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>bits<span class="token punctuation">[</span>pos<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"%5d:  "</span><span class="token punctuation">,</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"        "</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
        <span class="token comment">//打印操作码名称</span>
        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"%s"</span><span class="token punctuation">,</span> oi<span class="token operator">-></span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
        pos<span class="token operator">++</span><span class="token punctuation">;</span>
        <span class="token keyword">switch</span><span class="token punctuation">(</span>oi<span class="token operator">-></span>fmt<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">case</span> OP_FMT_none_int<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %d"</span><span class="token punctuation">,</span> op <span class="token operator">-</span> OP_push_0<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_npopx<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %d"</span><span class="token punctuation">,</span> op <span class="token operator">-</span> OP_call0<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_u8<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %u"</span><span class="token punctuation">,</span> <span class="token function">get_u8</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_i8<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %d"</span><span class="token punctuation">,</span> <span class="token function">get_i8</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_u16<span class="token operator">:</span>
        <span class="token keyword">case</span> OP_FMT_npop<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %u"</span><span class="token punctuation">,</span> <span class="token function">get_u16</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_npop_u16<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %u,%u"</span><span class="token punctuation">,</span> <span class="token function">get_u16</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">get_u16</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_i16<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %d"</span><span class="token punctuation">,</span> <span class="token function">get_i16</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_i32<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %d"</span><span class="token punctuation">,</span> <span class="token function">get_i32</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_u32<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %u"</span><span class="token punctuation">,</span> <span class="token function">get_u32</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">if</span> <span class="token expression">SHORT_OPCODES</span></span>
        <span class="token keyword">case</span> OP_FMT_label8<span class="token operator">:</span>
            addr <span class="token operator">=</span> <span class="token function">get_i8</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">goto</span> has_addr1<span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_label16<span class="token operator">:</span>
            addr <span class="token operator">=</span> <span class="token function">get_i16</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">goto</span> has_addr1<span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
        <span class="token keyword">case</span> OP_FMT_label<span class="token operator">:</span>
            addr <span class="token operator">=</span> <span class="token function">get_u32</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">goto</span> has_addr1<span class="token punctuation">;</span>
        has_addr1<span class="token operator">:</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>pass <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %u:%u"</span><span class="token punctuation">,</span> addr<span class="token punctuation">,</span> label_slots<span class="token punctuation">[</span>addr<span class="token punctuation">]</span><span class="token punctuation">.</span>pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>pass <span class="token operator">==</span> <span class="token number">2</span><span class="token punctuation">)</span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %u:%u"</span><span class="token punctuation">,</span> addr<span class="token punctuation">,</span> label_slots<span class="token punctuation">[</span>addr<span class="token punctuation">]</span><span class="token punctuation">.</span>pos2<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>pass <span class="token operator">==</span> <span class="token number">3</span><span class="token punctuation">)</span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %u"</span><span class="token punctuation">,</span> addr <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_label_u16<span class="token operator">:</span>
            addr <span class="token operator">=</span> <span class="token function">get_u32</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>pass <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %u:%u"</span><span class="token punctuation">,</span> addr<span class="token punctuation">,</span> label_slots<span class="token punctuation">[</span>addr<span class="token punctuation">]</span><span class="token punctuation">.</span>pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>pass <span class="token operator">==</span> <span class="token number">2</span><span class="token punctuation">)</span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %u:%u"</span><span class="token punctuation">,</span> addr<span class="token punctuation">,</span> label_slots<span class="token punctuation">[</span>addr<span class="token punctuation">]</span><span class="token punctuation">.</span>pos2<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>pass <span class="token operator">==</span> <span class="token number">3</span><span class="token punctuation">)</span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %u"</span><span class="token punctuation">,</span> addr <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">",%u"</span><span class="token punctuation">,</span> <span class="token function">get_u16</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos <span class="token operator">+</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">if</span> <span class="token expression">SHORT_OPCODES</span></span>
        <span class="token keyword">case</span> OP_FMT_const8<span class="token operator">:</span>
            idx <span class="token operator">=</span> <span class="token function">get_u8</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">goto</span> has_pool_idx<span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
        <span class="token keyword">case</span> OP_FMT_const<span class="token operator">:</span>
            idx <span class="token operator">=</span> <span class="token function">get_u32</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">goto</span> has_pool_idx<span class="token punctuation">;</span>
        has_pool_idx<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %u: "</span><span class="token punctuation">,</span> idx<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>idx <span class="token operator">&lt;</span> cpool_count<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                <span class="token function">JS_DumpValue</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> cpool<span class="token punctuation">[</span>idx<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_atom<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">print_atom</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token function">get_u32</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_atom_u8<span class="token operator">:</span><span class="token comment">//表明操作数是字符串和u8，因此，下面是先打印字符串，后打印数字</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">print_atom</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token function">get_u32</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">",%d"</span><span class="token punctuation">,</span> <span class="token function">get_u8</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos <span class="token operator">+</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_atom_u16<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">print_atom</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token function">get_u32</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">",%d"</span><span class="token punctuation">,</span> <span class="token function">get_u16</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos <span class="token operator">+</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_atom_label_u8<span class="token operator">:</span>
        <span class="token keyword">case</span> OP_FMT_atom_label_u16<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">print_atom</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token function">get_u32</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            addr <span class="token operator">=</span> <span class="token function">get_u32</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos <span class="token operator">+</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>pass <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">",%u:%u"</span><span class="token punctuation">,</span> addr<span class="token punctuation">,</span> label_slots<span class="token punctuation">[</span>addr<span class="token punctuation">]</span><span class="token punctuation">.</span>pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>pass <span class="token operator">==</span> <span class="token number">2</span><span class="token punctuation">)</span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">",%u:%u"</span><span class="token punctuation">,</span> addr<span class="token punctuation">,</span> label_slots<span class="token punctuation">[</span>addr<span class="token punctuation">]</span><span class="token punctuation">.</span>pos2<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>pass <span class="token operator">==</span> <span class="token number">3</span><span class="token punctuation">)</span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">",%u"</span><span class="token punctuation">,</span> addr <span class="token operator">+</span> pos <span class="token operator">+</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>oi<span class="token operator">-></span>fmt <span class="token operator">==</span> OP_FMT_atom_label_u8<span class="token punctuation">)</span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">",%u"</span><span class="token punctuation">,</span> <span class="token function">get_u8</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos <span class="token operator">+</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">else</span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">",%u"</span><span class="token punctuation">,</span> <span class="token function">get_u16</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos <span class="token operator">+</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_none_loc<span class="token operator">:</span>
            idx <span class="token operator">=</span> <span class="token punctuation">(</span>op <span class="token operator">-</span> OP_get_loc0<span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">4</span><span class="token punctuation">;</span>
            <span class="token keyword">goto</span> has_loc<span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_loc8<span class="token operator">:</span>
            idx <span class="token operator">=</span> <span class="token function">get_u8</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">goto</span> has_loc<span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_loc<span class="token operator">:</span>
            idx <span class="token operator">=</span> <span class="token function">get_u16</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
        has_loc<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %d: "</span><span class="token punctuation">,</span> idx<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>idx <span class="token operator">&lt;</span> var_count<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                <span class="token function">print_atom</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> vars<span class="token punctuation">[</span>idx<span class="token punctuation">]</span><span class="token punctuation">.</span>var_name<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_none_arg<span class="token operator">:</span>
            idx <span class="token operator">=</span> <span class="token punctuation">(</span>op <span class="token operator">-</span> OP_get_arg0<span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">4</span><span class="token punctuation">;</span>
            <span class="token keyword">goto</span> has_arg<span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_arg<span class="token operator">:</span>
            idx <span class="token operator">=</span> <span class="token function">get_u16</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
        has_arg<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %d: "</span><span class="token punctuation">,</span> idx<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>idx <span class="token operator">&lt;</span> arg_count<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                <span class="token function">print_atom</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> args<span class="token punctuation">[</span>idx<span class="token punctuation">]</span><span class="token punctuation">.</span>var_name<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_none_var_ref<span class="token operator">:</span>
            idx <span class="token operator">=</span> <span class="token punctuation">(</span>op <span class="token operator">-</span> OP_get_var_ref0<span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">4</span><span class="token punctuation">;</span>
            <span class="token keyword">goto</span> has_var_ref<span class="token punctuation">;</span>
        <span class="token keyword">case</span> OP_FMT_var_ref<span class="token operator">:</span>
            idx <span class="token operator">=</span> <span class="token function">get_u16</span><span class="token punctuation">(</span>tab <span class="token operator">+</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
        has_var_ref<span class="token operator">:</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" %d: "</span><span class="token punctuation">,</span> idx<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>idx <span class="token operator">&lt;</span> closure_var_count<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                <span class="token function">print_atom</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> closure_var<span class="token punctuation">[</span>idx<span class="token punctuation">]</span><span class="token punctuation">.</span>var_name<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">default</span><span class="token operator">:</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        pos <span class="token operator">+=</span> oi<span class="token operator">-></span>size <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>source<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>in_source<span class="token punctuation">)</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">print_lines</span><span class="token punctuation">(</span>source<span class="token punctuation">,</span> line<span class="token punctuation">,</span> INT32_MAX<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token function">js_free</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> bits<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>字节码的打印由dump_byte_code来实现。它分两部来完成功能。第一步遍历了字节码，找出label的位置，标记在bits数组中。第二步，重新遍历字节码，逐步将操作码+操作数作为单个整体解析出来。单个操作码+操作数取出来之后，就打印该内容。先是打印对应的十六进制字节码。接着根据第一步设置的bits判断该字节码是否是label。如果是就打印标签，否则就打印空白字符。紧接着是打印操作码的名称，然后根据操作码对应的操作数类型，将其打印出来。<br>操作码的定义</p>
<pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">typedef</span> <span class="token keyword">struct</span> <span class="token class-name">JSOpCode</span> <span class="token punctuation">&#123;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifdef</span> <span class="token expression">DUMP_BYTECODE</span></span>
    <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>name<span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
    <span class="token class-name">uint8_t</span> size<span class="token punctuation">;</span> <span class="token comment">/* in bytes */</span>
    <span class="token comment">/* the opcodes remove n_pop items from the top of the stack, then
       pushes n_push items */</span>
    <span class="token class-name">uint8_t</span> n_pop<span class="token punctuation">;</span>
    <span class="token class-name">uint8_t</span> n_push<span class="token punctuation">;</span>
    <span class="token class-name">uint8_t</span> fmt<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span> JSOpCode<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>举个例子，比如我们解析到了一个操作码是：scope_put_var_init。它对应的操作码结构体是 </p>
<pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token punctuation">&#123;</span>
    <span class="token string">"scope_put_var_init"</span><span class="token punctuation">,</span> <span class="token comment">//name</span>
    <span class="token number">7</span><span class="token punctuation">,</span><span class="token comment">//size in bytes</span>
    <span class="token number">0</span><span class="token punctuation">,</span> <span class="token comment">//n_pop</span>
    <span class="token number">2</span><span class="token punctuation">,</span> <span class="token comment">//n_push</span>
    OP_FMT_atom_u16 <span class="token comment">//fmt</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>假设没有标签，我们首先会打印操作码的名称，也就是scope_put_var_init，接着根据操作数类型是OP_FMT_atom_u16，跳转到对应的case进行打印。</p>
<pre><code>case OP_FMT_atom_u16:
    printf(&quot; &quot;);
    print_atom(ctx, get_u32(tab + pos));
    printf(&quot;,%d&quot;, get_u16(tab + pos + 4));
    break;
</code></pre>
<p>可以看到，先打印了紧随其后的一个字符串。然后再打印了一个数字。<br>什么含义呢？这个需要回到生成字节码的源码中去看了。</p>
<pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">//  </span>
<span class="token function">emit_op</span><span class="token punctuation">(</span>s<span class="token punctuation">,</span> <span class="token punctuation">(</span>tok <span class="token operator">==</span> TOK_CONST <span class="token operator">||</span> tok <span class="token operator">==</span> TOK_LET<span class="token punctuation">)</span> <span class="token operator">?</span>
                        OP_scope_put_var_init <span class="token operator">:</span> OP_scope_put_var<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">emit_atom</span><span class="token punctuation">(</span>s<span class="token punctuation">,</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">emit_u16</span><span class="token punctuation">(</span>s<span class="token punctuation">,</span> fd<span class="token operator">-></span>scope_level<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>从QuickJS代码中，可以看到，先是在字节码中添加<strong>OP_scope_put_var_init</strong>操作码，然后再添加<strong>操作数1</strong>–name，然后再添加<strong>操作数2</strong>–scope_level。</p>
 

<div class="p-2 pe-4">
     
        <a href="/2022/05/05/QuickJS-JSString-JSAtom/" class="btn btn-outline-secondary btn-sm float-start">
            <small>
                < 上一篇：QuickJS JSString&JSAtom
            </small>
        </a>
     
     
        <a href="/2022/05/05/QuickJS%E6%93%8D%E4%BD%9C%E7%A0%81/" class="btn btn-outline-secondary btn-sm float-end" >
            <small>
                下一篇：QuickJS操作码 >
            </small>
        </a>
     
</div>
                        </div>
                    </div>

                    <!-- sidebar -->
                    <div id="slidebar">
                        <div class="border-auto ps-2 pe-1 pb-2 pt-2">
    
        <!-- 侧边栏 分类 -->
<div class="card mb-3">
    <h6 class="card-header tag-hover"><i class="fa fa-folder-open pe-2"></i>分类
        
    </h6>
    <div class="card-body">
        <ul class="list-group border-0">
            
            
             
            <a class="list-group-item border-0 pt-0 pb-0 ps-1" href="/categories/QuickJS/ ">
                QuickJS <span class="badge bg-secondary float-end m-1">3</span>
            </a>
              
        </ul>

        <ul class="list-group border-0 collapse" id="category">
            
        </ul>
    </div>
</div>

 
    
        <!-- 侧边栏 标签 -->
<div class="card mb-3">
    <h6 class="card-header tag-hover"><i class="fa fa-tag pe-2"></i>标签
        
    </h6>

    <div class="card-body tag-hover">
        
        
             
            <a class="text-decoration-none border-0 d-inline-flex link-dark pt-0 pb-0 p-0" href="/tags/QuickJS/ ">
                QuickJS <span class="badge bg-secondary float-end m-1">6</span>
            </a>
          

        <span id="tags" class="collapse">
            
        </span>
    </div>
</div>
 
    
        <div class="card mb-3">
    <h6 class="card-header"><i class="fa fa-clock-o pe-2"></i>最近文章</h6>
    <div class="card-body tag-hover">
        <ul class="list-group border-0">
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/05/QuickJS-JSString-JSAtom/ ">
                    <small> QuickJS JSString&JSAtom </small>
                </a>
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/05/QuickJS%E5%AD%97%E8%8A%82%E7%A0%81%E6%89%93%E5%8D%B0/ ">
                    <small> QuickJS字节码打印 </small>
                </a>
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/05/QuickJS%E6%93%8D%E4%BD%9C%E7%A0%81/ ">
                    <small> QuickJS操作码 </small>
                </a>
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/12/QuickJS%E6%95%B0%E5%AD%97%E5%AD%97%E9%9D%A2%E9%87%8F/ ">
                    <small> QuickJS数字字面量 </small>
                </a>
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/16/QuickJS-JavaScript%E4%B8%96%E7%95%8C%E7%9A%84%E5%8E%9F%E5%A7%8B%E5%8E%9F%E5%9E%8B%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%BB%BA%E7%AB%8B/ ">
                    <small> QuickJS JavaScript世界的原始原型对象的建立 </small>
                </a>
            
             
        </ul>
    </div>
</div> 
    
        <div class="card mb-3">
    <h6 class="card-header"><i class="fa fa-link pe-2"></i>友情链接</h6>
    <div class="card-body tag-hover">
        <ul class="list-group border-0">
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6 text" target="_blank" rel="noopener" href="https://blog.csdn.net/jayyuz ">
                    <small>CSDN</small>
                </a>
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6 text" target="_blank" rel="noopener" href="https://smartlink.xin ">
                    <small>Smartlink</small>
                </a>
             
        </ul>
    </div>
</div> 
    
</div>
                    </div>
                </div>
            </main>


            <!-- footer -->
            <footer id="footer" class="bg-dark pt-3 pb-0 mt-5">
    <div class="container pb-4 pt-4 text-center">
        <p class="text-muted tag-hover"> Copyright © 2022 <a class="link-secondary text-decoration-none" target="_blank" rel="noopener" href="https://hexo.io"> SmartLink </a><br> <a class="link-secondary text-decoration-none" target="_blank" rel="noopener" href="https://github.com/smile-yan/hexo-theme-heyan"> Hexo </a> Theme <a class="link-secondary text-decoration-none" target="_blank" rel="noopener" href="https://github.com/smile-yan/hexo-theme-heyan"> heyan </a> 
            <br>
            <a class="link-secondary text-decoration-none" target="_blank" rel="noopener" href="https://beian.miit.gov.cn/#/Integrated/index">
                 
            </a>
        </p>
    </div>
</footer>
    <!-- hexo injector body_end start -->
<script src="/assets/prism-bundle.js"></script>
<script src="/assets/prism-plus.js" data-pjax=""></script>
<!-- hexo injector body_end end --><!-- hexo-inject:begin --><!-- hexo-inject:end --></body>
    <script>
        // 获取屏幕高度 document.documentElement.clientHeight
        console.log(document.documentElement.clientHeight);
        // 获取屏幕宽度 document.documentElement.clientWidth
        console.log(document.documentElement.clientWidth);
        if (document.documentElement.clientHeight > document.documentElement.clientWidth) {
            console.log('remove slidebar')
            document.getElementById("slidebar").remove()
            document.getElementById("content").className = "col-md-12";//单个class  
        } else {
            document.getElementById("slidebar").className = "col-md-2";//单个class  
            document.getElementById("content").className = "col-md-10";//单个class  
        }
    </script>
    <!-- https://cdn.jsdelivr.net/npm/vanta@0.5.22/dist/vanta.birds.min.js -->
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r121/three.min.js"></script> -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/vanta@0.5.22/dist/vanta.dots.min.js"></script>
    <script>
        VANTA.DOTS({
            el: "#footer",
            mouseControls: true,
            touchControls: true,
            gyroControls: false,
            minHeight: 200.00,
            minWidth: 200.00,
            scale: 1.00,
            scaleMobile: 1.00,
            size: 2.20,
            spacing: 13.00
        })
    </script> -->

    <!-- <script src="https://cdn.jsdelivr.net/npm/vanta@0.5.22/dist/vanta.clouds2.min.js"></script>
    <script>
        VANTA.CLOUDS2({
            el: "#footer",
            mouseControls: true,
            touchControls: true,
            gyroControls: false,
            minHeight: 200.00,
            minWidth: 200.00,
            scale: 1.00,
            speed: 2.10,
            texturePath: "https://www.vantajs.com/gallery/noise.png"
        })
    </script> -->

</html>